package org.liaohailong.library.event;

import android.os.Handler;
import android.os.Looper;

import android.util.Log;
import android.webkit.ValueCallback;


import androidx.annotation.NonNull;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;


/**
 * create by liaohailong
 * time 2022/9/22 15:17
 * desc: 消息时间 订阅发布功能
 */
public class MessageController {
    private static final String TAG = "MessageController";

    private static final class SingletonHolder {
        private static final MessageController INSTANCE = new MessageController();
    }

    public static MessageController getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private void log(@NonNull String format, Object... args) {
        String msg = String.format(format, args);
        Log.i(TAG, msg);
    }

    /**
     * 主线程运行
     */
    private final Handler mainHandler = new Handler(Looper.getMainLooper());

    /**
     * 根据tag分类缓存 消息事件
     */
    private final Map<Object, LinkedList<MessageReflectInfo>> tagMap = new HashMap<>();

    /**
     * 根据消息事件类型 分类缓存订阅者
     */
    private final Map<Class<?>, LinkedList<WeakReference<MessageReflectInfo>>> eventMap = new HashMap<>();

    /**
     * 写入锁
     */
    private final Object writeLock = new Object();


    public void register(@NonNull Object owner) {
        MessageEventHelper.traversal(owner, new ValueCallback<MessageReflectInfo>() {
            @Override
            public void onReceiveValue(MessageReflectInfo value) {
                synchronized (writeLock) {
                    Class<?> eventClz = value.getEventClz();
                    // 记录订阅者，宿主：订阅函数
                    LinkedList<MessageReflectInfo> methods = tagMap.get(owner);
                    if (methods == null) {
                        methods = new LinkedList<>();
                        tagMap.put(owner, methods);
                    }
                    methods.addLast(value);

                    // 记录订阅者，消息类型：订阅函数
                    LinkedList<WeakReference<MessageReflectInfo>> subscribes = eventMap.get(eventClz);
                    if (subscribes == null) {
                        subscribes = new LinkedList<>();
                        eventMap.put(eventClz, subscribes);
                    }
                    subscribes.add(new WeakReference<>(value));

                    // log输出，方便查看和分析问题
                    String ownerName = owner.getClass().getSimpleName();
                    String eventName = eventClz.getSimpleName();
                    log("发现订阅者：%s, 注册消息：%s", ownerName, eventName);
                }
            }
        });
    }


    public void unregister(@NonNull Object owner) {
        synchronized (writeLock) {
            // 标签分类集合 移除订阅者
            tagMap.remove(owner);
            // log输出，方便查看和分析问题
            String ownerName = owner.getClass().getSimpleName();
            log("注销：%s", ownerName);
        }
    }

    public void post2main(@NonNull Object event) {
        mainHandler.post(() -> post(event));
    }

    public void post(@NonNull Object event) {
        synchronized (writeLock) {
            LinkedList<WeakReference<MessageReflectInfo>> subscribes = eventMap.get(event.getClass());
            for (WeakReference<MessageReflectInfo> reference : subscribes) {
                MessageReflectInfo subscribe = reference.get();
                if (subscribe != null) {
                    subscribe.onEvent(event);
                }
            }
        }
    }


}
